package com.pokeoffice.client;

import java.io.Serializable;
import java.sql.Connection;

import com.pokeoffice.database.Control;
import com.pokeoffice.gui.AdminHome;
import com.pokeoffice.gui.Login;
import com.pokeoffice.gui.NurseHome;
import com.pokeoffice.gui.ProfessorHome;
import com.pokeoffice.gui.TrainerHome;
import com.pokeoffice.users.User;
import com.pokeoffice.users.UserType;

/**
 * The Class Session.
 *
 * @author Kyle Davis
 * 
 * (Pattern: Session) This is the class that interfaces with the GUI,
 * builds appropriate commands, and send them to the client to pass
 * on to the mediator
 * 
 * TODO Everything
 */
public class Session implements Runnable, Serializable {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -6931659071917447938L;

	/** The client. */
	public Client client = null;
	
	/** The state. */
	public State state = null;
	
	/** The user. */
	public User user = null;

	/**
	 * Instantiates a new session.
	 *
	 * @param client the client
	 */
	public Session(Client client) {
		this.client = client;
		this.state = new State();
		state.add(new Login(this));
		state.display();
	}

	/**
	 * Login.
	 *
	 * @param username the username
	 * @param pass the pass
	 */
	public void login(String username, char[] pass) {
		StringBuilder sb = new StringBuilder();

		for (char c : pass) {
			sb.append(c);
		}

		String password = sb.toString();
		Control ctrl = Control.get();

		int attempt = ctrl.getLoginAttempt(User.getID(username));

		boolean connected = false;
		if (attempt < ctrl.MAX_LOGIN_ATTEMPTS && !(ctrl.isBlocked(User.getID(username)))) {
			Connection con = ctrl.connect(username, password);
			connected = (con != null);
			if (connected) {
				state.setConnection(con);
				user = ctrl.readUser(con, User.getID(username));
				if (user != null) {
					state.clear();

					if (user.getUserType() == UserType.ADMIN) {
						state.add(new AdminHome(this));
					} else if (user.getUserType() == UserType.PROFESSOR) {
						state.add(new ProfessorHome(this));
					} else if (user.getUserType() == UserType.NURSE) {
						state.add(new NurseHome(this));
					} else if (user.getUserType() == UserType.TRAINER) {
						state.add(new TrainerHome(this));
					}
					
					state.display();
					ctrl.resetLoginAttempts(User.getID(username));
					ctrl.resetBlock(User.getID(username));
				}
			} else {
				ctrl.setLoginAttempts(User.getID(username), attempt + 1);
				ctrl.block(User.getID(username));
			}
		} else {
			//TODO POP UP LOCKOUT MESSAGE
			System.out.println("Locked Out");
		}

		// Clear password for safety
		for (int i = 0; i < pass.length; i++) {
			pass[i] = 0;
		}
	}

	/**
	 * Logout.
	 */
	public void logout () {
		state.clear();
		state.add(new Login(this));
		state.display();
	}

	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run () {

	}

	/**
	 * Shutdown.
	 */
	public synchronized void shutdown() {
		state.hide();
		state = null;
		client = null;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return "Session: ";
	}
	
	/**
	 * Display.
	 */
	public void display() {
		state.display();
	}
	
	/**
	 * Clear.
	 */
	public void clear() {
		state.clear();
	}
}
